<?php
/**
 * DBERP 进销存系统
 *
 * ==========================================================================
 * @link      http://www.dberp.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   http://www.dberp.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Customer\Controller;

use Admin\Entity\Region;
use Customer\Entity\Supplier;
use Customer\Entity\SupplierCategory;
use Customer\Form\ImportSupplierForm;
use Customer\Form\SearchSupplierForm;
use Customer\Form\SupplierForm;
use Customer\Service\SupplierCategoryManager;
use Customer\Service\SupplierManager;
use Doctrine\ORM\EntityManager;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use Purchase\Entity\Order;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\JsonModel;

class SupplierController extends AbstractActionController
{
    private $translator;
    private $entityManager;
    private $supplierCategoryManager;
    private $supplierManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        SupplierCategoryManager $supplierCategoryManager,
        SupplierManager $supplierManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->supplierCategoryManager  = $supplierCategoryManager;
        $this->supplierManager  = $supplierManager;
    }

    /**
     * 供应商列表
     * @return array
     */
    public function indexAction()
    {
        $array = [];

        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchSupplierForm();
        $searchForm->get('supplier_category_id')->setValueOptions($this->customerCommon()->supplierCategoryOptions());
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }
        $array['searchForm'] = $searchForm;

        $query = $this->entityManager->getRepository(Supplier::class)->findAllSupplier($search);
        $array['supplierList'] = $this->adminCommon()->erpPaginator($query, $page);

        return $array;
    }

    /**
     * 供应商添加
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addAction()
    {
        $form = new SupplierForm($this->entityManager);
        $form->get('supplierCategoryId')->setValueOptions($this->customerCommon()->supplierCategoryOptions());

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $this->supplierManager->addSupplier($data, $this->adminSession('admin_id'));

                $message = sprintf($this->translator->translate('供应商 %s 添加成功！'), $data['supplierName']);
                $this->adminCommon()->addOperLog($message, $this->translator->translate('供应商'));

                return $this->redirect()->toRoute('supplier');
            }
        }

        if (empty($data)) $form->setData(['supplierCode' => $this->codeAndNumber()->createSupplierCode()]);

        return ['form' => $form, 'region' => $this->adminCommon()->getRegionSub()];
    }

    /**
     * 编辑供应商
     * @return array|\Laminas\Http\Response
     */
    public function editAction()
    {
        $supplierId = (int) $this->params()->fromRoute('id', -1);

        $supplierInfo = $this->entityManager->getRepository(Supplier::class)->findOneBySupplierId($supplierId);
        if($supplierInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该供应商不存在！'));
            return $this->redirect()->toRoute('supplier');
        }

        $form = new SupplierForm($this->entityManager, $supplierInfo);
        $form->get('supplierCategoryId')->setValueOptions($this->customerCommon()->supplierCategoryOptions());

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $this->supplierManager->editSupplier($data, $supplierInfo);

                $message = sprintf($this->translator->translate('供应商 %s 编辑成功！'), $data['supplierName']);
                $this->adminCommon()->addOperLog($message, $this->translator->translate('供应商'));

                return $this->redirect()->toRoute('supplier');
            }
        } else $form->setData($supplierInfo->valuesArray());

        return ['supplier' => $supplierInfo, 'form' => $form, 'region' => $this->adminCommon()->getRegionSub()];
    }

    /**
     * 批量修改
     * @return \Laminas\Http\Response
     */
    public function updateAllAction()
    {
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            if(!empty($data['select_id']) and !empty($data['editAllState'])) {
                $this->supplierManager->editAllSupplier($data);

                $message = $this->translator->translate('批量处理成功！');
                $this->adminCommon()->addOperLog($message, $this->translator->translate('供应商'));
            }
        }
        return $this->redirect()->toRoute('supplier');
    }

    /**
     * 删除供应商
     * @return \Laminas\Http\Response
     */
    public function deleteAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $supplierId = (int) $this->params()->fromRoute('id', -1);

        $supplierInfo = $this->entityManager->getRepository(Supplier::class)->findOneBySupplierId($supplierId);
        if($supplierInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该供应商不存在！'));
            return $this->redirect()->toRoute('supplier');
        }

        $order = $this->entityManager->getRepository(Order::class)->findOneBy(['supplierId' => $supplierId]);
        if($order) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('有该供应商的采购订单，不能删除！'));
            return $this->redirect()->toRoute('supplier');
        }

        $this->supplierManager->deleteSupplier($supplierInfo);

        $this->getEventManager()->trigger('supplier.delete.post', $this, ['supplierId' => $supplierId]);

        $message = sprintf($this->translator->translate('供应商 %s 删除成功！'), $supplierInfo->getSupplierName());
        $this->adminCommon()->addOperLog($message, $this->translator->translate('供应商'));

        return $this->adminCommon()->toReferer();
    }

    /**
     * 导入供应商
     * @return ImportSupplierForm[]|\Laminas\Http\Response
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     */
    public function importSupplierAction()
    {
        @set_time_limit(600);

        $form = new ImportSupplierForm();

        if($this->getRequest()->isPost()) {
            $data = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $supplierCategoryList = $this->entityManager->getRepository(SupplierCategory::class)->findAll();
                if (empty($supplierCategoryList)) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('系统中没有供应商分类，请添加后再导入 !'));
                    return $this->redirect()->toRoute('supplier', ['action' => 'importSupplier']);
                }

                $supplierCategoryArray = [];
                foreach ($supplierCategoryList as $categoryValue) {
                    $supplierCategoryArray[$categoryValue->getSupplierCategoryId()] = $categoryValue->getSupplierCategoryName();
                }

                $readerXlsx     = new Xlsx();
                $spreadsheet    = $readerXlsx->load($data['importFile']['tmp_name']);
                $sheetData      = $spreadsheet->getActiveSheet()->toArray(null, false, false, true);
                $rowCount       = count($sheetData);
                if ($rowCount == 1) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('无导入信息!'));
                    return $this->redirect()->toRoute('supplier', ['action' => 'importSupplier']);
                }

                $adminId        = $this->adminSession('admin_id');
                $regionStrArray = [];
                $nextSupplierId = $this->entityManager->getRepository(Supplier::class)->getMaxSupplierId();
                $insertSupplierSql = '';
                $insertSupplierSqlArray = [];
                for ($i = 2; $i <= $rowCount; $i++) {
                    $supplierCategoryId = (int)$sheetData[$i]['A'];
                    $supplierName = addslashes($sheetData[$i]['B']);
                    $supplierCode = $sheetData[$i]['C'];
                    $regionId = (int)$sheetData[$i]['D'];
                    if (!isset($supplierCategoryArray[$supplierCategoryId]) || empty($supplierName) || empty($supplierCode) || $regionId <= 0) {
                        continue;
                    }

                    $supplierAddress = addslashes($sheetData[$i]['E']);
                    $supplierContacts = addslashes($sheetData[$i]['F']);
                    $supplierPhone = $sheetData[$i]['G'];
                    $supplierTelephone = $sheetData[$i]['H'];
                    $supplierEmail = $sheetData[$i]['I'];
                    $supplierBank = addslashes($sheetData[$i]['J']);
                    $supplierBankAccount = $sheetData[$i]['K'];
                    $supplierTax = $sheetData[$i]['L'];
                    $supplierInfo = addslashes($sheetData[$i]['M']);

                    $regionStr  = '';
                    if (isset($regionStrArray[$regionId])) $regionStr = $regionStrArray[$regionId];
                    else {
                        $regionInfo = $this->entityManager->getRepository(Region::class)->findOneBy(['regionId' => $regionId]);
                        if (!empty($regionInfo)) {
                            $regionStr = $this->entityManager->getRepository(Region::class)->getRegionStr($regionInfo->getRegionPath());
                            $regionStrArray[$regionId] = $regionStr;
                        }
                    }

                    $insertSupplierSql .= "($nextSupplierId, $supplierCategoryId, '$supplierName', '$supplierCode', $regionId, '$regionStr', '$supplierAddress', '$supplierContacts', '$supplierPhone', '$supplierTelephone', '$supplierEmail', '$supplierBank', '$supplierBankAccount', '$supplierTax', '$supplierInfo', $adminId),";
                    if ($i%3000 == 0) {
                        $insertSupplierSqlArray[] = rtrim($insertSupplierSql, ',');
                        $insertSupplierSql = '';
                    }

                    $nextSupplierId++;
                }

                if (!empty($insertSupplierSql)) {
                    $this->entityManager->beginTransaction();
                    try {
                        $this->entityManager->getConnection()->executeStatement('INSERT INTO dberp_supplier (supplier_id, supplier_category_id, supplier_name, supplier_code, region_id, region_values, supplier_address, supplier_contacts, supplier_phone, supplier_telephone, supplier_email, supplier_bank, supplier_bank_account, supplier_tax, supplier_info, admin_id) VALUES '.rtrim($insertSupplierSql, ','));
                        if (!empty($insertSupplierSqlArray)) foreach ($insertSupplierSqlArray as $insertSupplierSqlValue) {
                            $this->entityManager->getConnection()->executeStatement("INSERT INTO dberp_supplier (supplier_id, supplier_category_id, supplier_name, supplier_code, region_id, region_values, supplier_address, supplier_contacts, supplier_phone, supplier_telephone, supplier_email, supplier_bank, supplier_bank_account, supplier_tax, supplier_info, admin_id) VALUES $insertSupplierSqlValue");
                        }
                        $this->entityManager->commit();
                        $this->adminCommon()->addOperLog($this->translator->translate('供应商批量导入成功!'), $this->translator->translate('客户'));
                    } catch (\Exception $e) {
                        $this->entityManager->rollback();
                        $this->flashMessenger()->addErrorMessage($this->translator->translate('导入失败!'));
                        return $this->redirect()->toRoute('supplier', ['action' => 'importSupplier']);

                    }
                }
                return $this->redirect()->toRoute('supplier');
            }
        }

        return [
            'form' => $form
        ];
    }

    /**
     * 通过供应商id检索供应商
     * @return JsonModel
     */
    public function supplierIdSearchAction()
    {
        $array = ['state' => 'false'];

        $supplierId = (int) $this->params()->fromPost('supplierId', 0);
        $supplierInfo = $this->entityManager->getRepository(Supplier::class)->findOneBySupplierId($supplierId);
        if($supplierInfo) {
            $array['state'] = 'ok';
            $array['result']= $supplierInfo->valuesArray();
        }

        return new JsonModel($array);
    }
}